#ifndef _INV_INDEX_B_PLUS_STORAGE_HPP__ 
#define _INV_INDEX_B_PLUS_STORAGE_HPP__  1
#include <BPlusTreeNodesStorage.hpp>
#include <BPlusTree.hpp>
#include <BPlusTreeLeafsStorage.hpp>
#include <DocumentEntryIterator.hpp>
#include <Types.h>
#include <Util.hpp>
#include <InvIndexStorage.hpp>

// TODO протестировть производительность в различными значениями ширины дерева
#define TREE_INV_INDEX_STORAGE_WIDTH 8

namespace FTSS{ // Full Text Search System

	using namespace MAIL; // for tree working

	/**
	* @brief InvIndexBPlusStorage InvIndexBPlusStorage.hpp <InvIndexBPlusStorage.hpp>
	*/
	// хранлище инверсного индекса на базе B+ дерева
	class InvIndexBPlusStorage 
				: public InvIndexStorage{
	private:

		BPlusTree<BPlusTreeNodeData, BPlusTreeLeafData, TREE_INV_INDEX_STORAGE_WIDTH>* pBTree;
		// TODO исправить заглушку сохранения зон
		Size_t iDocNum;
		Zone *aZones;
		Size_t iZonesCount;	
	public:

		/**
		* @brief Constructor
		* @param pDataDirectory
		*/
		InvIndexBPlusStorage(CCHAR_P pDataDirectory){
			aZones = NULL;
			pBTree = new BPlusTree
					<BPlusTreeNodeData, BPlusTreeLeafData, TREE_INV_INDEX_STORAGE_WIDTH>
					(DirFilePath(pDataDirectory, "BNodesStorage.ftss").c_str(),
					 DirFilePath(pDataDirectory, "BNodesWhiteSpace.ftss").c_str(),
					 DirFilePath(pDataDirectory, "BLeafsStorage.ftss").c_str(),
					 DirFilePath(pDataDirectory, "BLeafsWhiteSpace.ftss").c_str());
		};

		/**
		  @brief Store document entry in specified data storage
		  @param iWordId - Word ID (word hash)
		  @param pEntry - Document Entry
		  @param iDocEntrySize - Document Entry size
		*/
		virtual void StoreDocumentEntry(WordId_t iWordId, 
						DocumentEntry * pEntry, 
						const Size_t & iDocEntrySize);

		/**
		  @brief Store number of documents in collection
		  @param iIDocNum - Number of documents
		*/
		virtual void StoreDocNum(const Size_t & iIDocNum);

		/**
		  @brief Get document entry from specified data storage
		  @param iWordId - Word ID (word hash)
		  @return pair of iterators
		*/
		virtual Pair<DocumentEntryIterator, DocumentEntryIterator> 
					GetDocumentEntry(const WordId_t & iWordId);

		/**
		  @brief Get document frequency for specified token
		  @param iWordId - Word ID (word hash)
		  @return document frequency (number of documents, contains whis word).
		*/
		virtual Size_t GetDF(const WordId_t & iWordId);

		/**
		  @brief Get number of documents in collection
		  @return Number of documents
		*/
		virtual Size_t GetDocNum();

		/**
		  @brief Check deletion flag of document
		*/
		virtual INT_32 IsDeleted(const Size_t & iDocNum);

		/**
		  @brief Get list of all available zones in this document collection
		  @param aZones - list of zones
		  @param iZonesCount - number of zones
		*/
		virtual void StoreZones(const Zone * aZones, 
					const INT_32 & iZonesCount);

		/**
		  @brief Get list of all available zones in this document collection
		  @param iZonesCount - number of zones
		  @return List of zones
		*/
		virtual Zone * GetZones(INT_32 & iZonesCount);

		virtual ~InvIndexBPlusStorage() throw() { fprintf(stderr, "pBTree.size=%lld\n", pBTree->size());  delete pBTree; if (aZones != NULL) delete aZones;};
	};
}
#endif
